https://cran.r-project.org/web/packages/rtweet/vignettes/intro.html
# twitter library
library(rtweet)
# plotting and pipes - tidyverse
library(ggplot2)
library(dplyr, warn.conflicts = FALSE)
options(dplyr.summarise.inform = FALSE) # Suppress summarise info
# text mining library
suppressPackageStartupMessages(library(tidyverse)) # suppress startup message
# date/time libaray
library(lubridate, warn.conflicts = FALSE)
get_token()
<Token>
<oauth_endpoint>
request: https://api.twitter.com/oauth/request_token
authorize: https://api.twitter.com/oauth/authenticate
access: https://api.twitter.com/oauth/access_token
<oauth_app> Data104
key: lfrCxMQkaeS6eg88o7Dnx96Uj
secret: <hidden>
<credentials> oauth_token, oauth_token_secret, user_id, screen_name
---
Retrieve most recent 3200 timelines of Trump and Biden
- use: ‘JoeBiden’ and ‘realDonaldTrump’
- don’t exclude anything
- save to csv file, so you don’t have to call the api subsequently, in case of long delays
- read the csv file into a dataframe and use that df for subsequent analysis.
- You will notice using the View (df) function that the the object structure of the original dataframe after the AP call is different from the one you read in. The original has embedded list objects, whereas the one read in is flattened. Also the date/time fields such as ‘create_at’ is char rather than Twitter’s POSIX time format. Use lubridate datetime functions (eg: as_datetime) to convert. Show the column names
tmls <- get_timelines(c("JoeBiden", "realDonaldTrump"), n = 3200, check = FALSE)
write_as_csv(tmls, "test.csv")
timelinesdf <- read_twitter_csv("test.csv")
table(timelinesdf$screen_name)
JoeBiden realDonaldTrump
3200 998
Download Data from a Hastag
rt <- search_tweets(
"Revit", n = 18000, include_rts = FALSE
)
Downloading [-----------------------------------------] 1%
Downloading [>----------------------------------------] 2%
Downloading [>----------------------------------------] 3%
Downloading [=>---------------------------------------] 4%
Downloading [=>---------------------------------------] 5%
Downloading [=>---------------------------------------] 6%
Downloading [==>--------------------------------------] 6%
Downloading [==>--------------------------------------] 7%
Downloading [==>--------------------------------------] 8%
Downloading [===>-------------------------------------] 9%
Downloading [===>-------------------------------------] 10%
Downloading [===>-------------------------------------] 11%
Downloading [====>------------------------------------] 11%
Downloading [====>------------------------------------] 12%
Downloading [====>------------------------------------] 13%
Downloading [=====>-----------------------------------] 14%
Downloading [=====>-----------------------------------] 15%
## preview tweets data
rt
## preview users data
users_data(rt)
## plot time series (if ggplot2 is installed)
ts_plot(rt)

write_as_csv(rt, "revit.csv")
df <- read_twitter_csv("revit.csv")
df
## plot time series of tweets
ts_plot(rt, "3 hours") +
ggplot2::theme_minimal() +
ggplot2::theme(plot.title = ggplot2::element_text(face = "bold")) +
ggplot2::labs(
x = NULL, y = NULL,
title = "Frequency of #rstats Twitter statuses from past 9 days",
subtitle = "Twitter status (tweet) counts aggregated using three-hour intervals",
caption = "\nSource: Data collected from Twitter's REST API via rtweet"
)

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3J0d2VldC92aWduZXR0ZXMvaW50cm8uaHRtbAoKYGBge3J9CiMgdHdpdHRlciBsaWJyYXJ5IApsaWJyYXJ5KHJ0d2VldCkKCiMgcGxvdHRpbmcgYW5kIHBpcGVzIC0gdGlkeXZlcnNlCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5ciwgd2Fybi5jb25mbGljdHMgPSBGQUxTRSkKb3B0aW9ucyhkcGx5ci5zdW1tYXJpc2UuaW5mb3JtID0gRkFMU0UpICMgU3VwcHJlc3Mgc3VtbWFyaXNlIGluZm8KCiMgdGV4dCBtaW5pbmcgbGlicmFyeQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeSh0aWR5dmVyc2UpKSAjIHN1cHByZXNzIHN0YXJ0dXAgbWVzc2FnZQoKIyBkYXRlL3RpbWUgbGliYXJheQpsaWJyYXJ5KGx1YnJpZGF0ZSwgd2Fybi5jb25mbGljdHMgPSBGQUxTRSkKYGBgCgpgYGB7cn0KZ2V0X3Rva2VuKCkKYGBgCgojIyBSZXRyaWV2ZSBtb3N0IHJlY2VudCAzMjAwIHRpbWVsaW5lcyBvZiBUcnVtcCBhbmQgQmlkZW4KICogdXNlOiDigJhKb2VCaWRlbuKAmSBhbmQg4oCYcmVhbERvbmFsZFRydW1w4oCZCiAqIGRvbuKAmXQgZXhjbHVkZSBhbnl0aGluZwogKiBzYXZlIHRvIGNzdiBmaWxlLCBzbyB5b3UgZG9u4oCZdCBoYXZlIHRvIGNhbGwgdGhlIGFwaSBzdWJzZXF1ZW50bHksIGluIGNhc2Ugb2YgbG9uZyBkZWxheXMKICogcmVhZCB0aGUgY3N2IGZpbGUgaW50byBhIGRhdGFmcmFtZSBhbmQgdXNlIHRoYXQgZGYgZm9yIHN1YnNlcXVlbnQgYW5hbHlzaXMuCiAgICAgKiBZb3Ugd2lsbCBub3RpY2UgdXNpbmcgdGhlIFZpZXcgKGRmKSBmdW5jdGlvbiB0aGF0IHRoZSB0aGUgb2JqZWN0IHN0cnVjdHVyZSBvZiB0aGUgb3JpZ2luYWwgZGF0YWZyYW1lIGFmdGVyIHRoZSBBUCBjYWxsIGlzIGRpZmZlcmVudCBmcm9tIHRoZSBvbmUgeW91IHJlYWQgaW4uIFRoZSBvcmlnaW5hbCBoYXMgZW1iZWRkZWQgbGlzdCBvYmplY3RzLCB3aGVyZWFzIHRoZSBvbmUgcmVhZCBpbiBpcyBmbGF0dGVuZWQuIEFsc28gdGhlIGRhdGUvdGltZSBmaWVsZHMgc3VjaCBhcyDigJhjcmVhdGVfYXTigJkgaXMgY2hhciByYXRoZXIgdGhhbiBUd2l0dGVy4oCZcyBQT1NJWCB0aW1lIGZvcm1hdC4gVXNlIGx1YnJpZGF0ZSBkYXRldGltZSBmdW5jdGlvbnMgKGVnOiBhc19kYXRldGltZSkgdG8gY29udmVydC4KU2hvdyB0aGUgY29sdW1uIG5hbWVzCgpgYGB7cn0KdG1scyA8LSBnZXRfdGltZWxpbmVzKGMoIkpvZUJpZGVuIiwgInJlYWxEb25hbGRUcnVtcCIpLCBuID0gMzIwMCwgY2hlY2sgPSBGQUxTRSkKd3JpdGVfYXNfY3N2KHRtbHMsICJ0ZXN0LmNzdiIpCmBgYAoKCgpgYGB7cn0KdGltZWxpbmVzZGYgPC0gcmVhZF90d2l0dGVyX2NzdigidGVzdC5jc3YiKQpgYGAKCgpgYGB7cn0KdGFibGUodGltZWxpbmVzZGYkc2NyZWVuX25hbWUpCmBgYAoKIyBEb3dubG9hZCBEYXRhIGZyb20gYSBIYXN0YWcKCmBgYHtyfQpydCA8LSBzZWFyY2hfdHdlZXRzKAogICJSZXZpdCIsIG4gPSAxODAwMCwgaW5jbHVkZV9ydHMgPSBGQUxTRQopCgojIyBwcmV2aWV3IHR3ZWV0cyBkYXRhCnJ0CgojIyBwcmV2aWV3IHVzZXJzIGRhdGEKdXNlcnNfZGF0YShydCkKCiMjIHBsb3QgdGltZSBzZXJpZXMgKGlmIGdncGxvdDIgaXMgaW5zdGFsbGVkKQp0c19wbG90KHJ0KQpgYGAKCmBgYHtyfQp3cml0ZV9hc19jc3YocnQsICJyZXZpdC5jc3YiKQpgYGAKCgpgYGB7cn0KZGYgPC0gcmVhZF90d2l0dGVyX2NzdigicmV2aXQuY3N2IikKYGBgCgoKYGBge3J9CmRmCmBgYAoKYGBge3J9CiMjIHBsb3QgdGltZSBzZXJpZXMgb2YgdHdlZXRzCnRzX3Bsb3QocnQsICIzIGhvdXJzIikgKwogIGdncGxvdDI6OnRoZW1lX21pbmltYWwoKSArCiAgZ2dwbG90Mjo6dGhlbWUocGxvdC50aXRsZSA9IGdncGxvdDI6OmVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKSkgKwogIGdncGxvdDI6OmxhYnMoCiAgICB4ID0gTlVMTCwgeSA9IE5VTEwsCiAgICB0aXRsZSA9ICJGcmVxdWVuY3kgb2YgI3JzdGF0cyBUd2l0dGVyIHN0YXR1c2VzIGZyb20gcGFzdCA5IGRheXMiLAogICAgc3VidGl0bGUgPSAiVHdpdHRlciBzdGF0dXMgKHR3ZWV0KSBjb3VudHMgYWdncmVnYXRlZCB1c2luZyB0aHJlZS1ob3VyIGludGVydmFscyIsCiAgICBjYXB0aW9uID0gIlxuU291cmNlOiBEYXRhIGNvbGxlY3RlZCBmcm9tIFR3aXR0ZXIncyBSRVNUIEFQSSB2aWEgcnR3ZWV0IgogICkKYGBgCgoK